package cn.janescott.inner.space.lib.support.service;

import cn.janescott.inner.space.lib.support.pagination.OrderDTO;
import cn.janescott.inner.space.lib.support.pagination.PaginationDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 服务拓展
 *
 * @author scott
 * Created by Scott on 2018/7/24
 */
public class ServiceSupport {

    /**
     * jpa分页
     */
    protected <T> List<T> executeQuery(JpaSpecificationExecutor<T> executor, Specification<T> specification, PaginationDTO op) {
        // 分页
        Pageable pageable = getPageable(op);

        // 查询
        Page<T> page = executor.findAll(specification, pageable);

        // 设置总页数
        op.setTotal((int) page.getTotalElements());

        // 返回查询结果
        return page.getContent();
    }

    private Pageable getPageable(PaginationDTO op) {
        if (null == op) {
            op = PaginationDTO.defaultPagination();
        }

        Pageable pageable;
        if (CollectionUtils.isEmpty(op.getOrders())) {
            pageable = PageRequest.of(op.getPage() - 1, op.getSize());
        } else {
            List<Sort.Order> orders = new ArrayList<>();
            for (OrderDTO orderDTO : op.getOrders()) {
                Sort.Order order;
                if (orderDTO.isDesc()) {
                    order = Sort.Order.desc(orderDTO.getName());
                } else {
                    order = Sort.Order.asc(orderDTO.getName());
                }
                orders.add(order);
            }
            Sort sort = Sort.by(orders);
            pageable = PageRequest.of(op.getPage() - 1, op.getSize(), sort);
        }
        return pageable;
    }

    protected <T, S> T convert(T target, S source) {
        BeanUtils.copyProperties(source, target);
        return target;
    }
}
